﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DocumentFormat.OpenXml.Wordprocessing;

namespace T2V.SharePoint.Workflows.TaskActions
{
    public class DeNghiHoanUngGenerator : BaseDoxGenerator
    {
        protected const string DateRequest = "DateRequest";
        protected const string UserRequest = "UserRequest";
        protected const string DepartmentRequest = "DepartmentRequest";
        protected const string TypeOfPayment = "TypeOfPayment";
        protected const string TypeOfRepayment = "TypeOfRepayment";

        protected const string Chief = "Chief";
        protected const string ChiefStatus = "ChiefStatus";
        protected const string ChiefComment = "ChiefComment";

        protected const string Approver = "Approver";
        protected const string ApproverStatus = "ApproverStatus";
        protected const string ApproverComment = "ApproverComment";

        protected const string Accountant = "Accountant";
        protected const string AccountantStatus = "AccountantStatus";
        protected const string AccountantComment = "AccountantComment";

        protected const string HeadAccountant = "HeadAccountant";
        protected const string HeadAccountantStatus = "HeadAccountantStatus";
        protected const string HeadAccountantComment = "HeadAccountantComment";

        protected const string AmountRepayment = "AmountRepayment";
        protected const string TotalAmount = "TotalAmount";
        protected const string DifferentAmount = "DifferentAmount";
        protected const string Currency = "Currency";

        protected const string RepaymentDetail = "RepaymentDetail";
        protected const string RepaymentDetail_No = "RepaymentDetail_No";
        protected const string RepaymentDetail_Title = "RepaymentDetail_Title";
        protected const string RepaymentDetail_Amount = "RepaymentDetail_Amount";

        protected const string ReferenceRequest = "ReferenceRequest";
        protected const string ReferenceRequest_No = "ReferenceRequest_No";
        protected const string ReferenceRequest_Title = "ReferenceRequest_Title";
        protected const string ReferenceRequest_DateRequest = "ReferenceRequest_DateRequest";
        protected const string ReferenceRequest_UserRequest = "ReferenceRequest_UserRequest";
        protected const string ReferenceRequest_DepartmentRequest = "ReferenceRequest_DepartmentRequest";

        public DeNghiHoanUngGenerator(DocumentGenerationInfo generationInfo)
            : base(generationInfo)
        {

        }

        #region Overridden methods

        /// <summary>
        /// Gets the place holder tag to type collection.
        /// </summary>
        /// <returns></returns>
        protected override Dictionary<string, PlaceHolderType> GetPlaceHolderTagToTypeCollection()
        {
            Dictionary<string, PlaceHolderType> placeHolderTagToTypeCollection = base.GetPlaceHolderTagToTypeCollection();

            // Handle recursive placeholders            
            placeHolderTagToTypeCollection.Add(RepaymentDetail, PlaceHolderType.Recursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest, PlaceHolderType.Recursive);

            // Handle non recursive placeholders
            placeHolderTagToTypeCollection.Add(DateRequest, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(UserRequest, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(DepartmentRequest, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(TypeOfPayment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(TypeOfRepayment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(Chief, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ChiefStatus, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ChiefComment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(Approver, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ApproverStatus, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ApproverComment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(Accountant, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(AccountantStatus, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(AccountantComment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(HeadAccountant, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(HeadAccountantStatus, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(HeadAccountantComment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(AmountRepayment, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(TotalAmount, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(DifferentAmount, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(Currency, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(RepaymentDetail_No, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(RepaymentDetail_Title, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(RepaymentDetail_Amount, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest_No, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest_Title, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest_DateRequest, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest_UserRequest, PlaceHolderType.NonRecursive);
            placeHolderTagToTypeCollection.Add(ReferenceRequest_DepartmentRequest, PlaceHolderType.NonRecursive);
            return placeHolderTagToTypeCollection;
        }

        /// <summary>
        /// Non recursive placeholder found.
        /// </summary>
        /// <param name="placeholderTag">The placeholder tag.</param>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        protected override void NonRecursivePlaceholderFound(string placeholderTag, OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (openXmlElementDataContext == null || openXmlElementDataContext.Element == null || openXmlElementDataContext.DataContext == null)
            {
                return;
            }

            string tagPlaceHolderValue = string.Empty;
            string tagGuidPart = string.Empty;
            GetTagValue(openXmlElementDataContext.Element as SdtElement, out tagPlaceHolderValue, out tagGuidPart);

            string tagValue = string.Empty;
            string content = string.Empty;

            // Reuse base class code and handle only tags unavailable in base class
            bool bubblePlaceHolder = true;

            switch (tagPlaceHolderValue)
            {
                case DateRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).DateRequest.ToString("dd/MM/yyyy");
                    content = tagValue;
                    break;
                case UserRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).UserRequest;
                    content = tagValue;
                    break;
                case DepartmentRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).DepartmentRequest;
                    content = tagValue;
                    break;
                case TypeOfPayment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).TypeOfPayment;
                    content = tagValue;
                    break;
                case TypeOfRepayment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).TypeOfRepayment;
                    content = tagValue;
                    break;
                case Chief:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).Chief;
                    content = tagValue;
                    break;
                case ChiefStatus:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).ChiefStatus;
                    content = tagValue;
                    break;
                case ChiefComment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).ChiefComment;
                    content = tagValue;
                    break;
                case Approver:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).Approver;
                    content = tagValue;
                    break;
                case ApproverStatus:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).ApproverStatus;
                    content = tagValue;
                    break;
                case ApproverComment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).ApproverComment;
                    content = tagValue;
                    break;
                case Accountant:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).Accountant;
                    content = tagValue;
                    break;
                case AccountantStatus:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).AccountantStatus;
                    content = tagValue;
                    break;
                case AccountantComment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).AccountantComment;
                    content = tagValue;
                    break;
                case HeadAccountant:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).HeadAccountant;
                    content = tagValue;
                    break;
                case HeadAccountantStatus:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).HeadAccountantStatus;
                    content = tagValue;
                    break;
                case HeadAccountantComment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).HeadAccountantComment;
                    content = tagValue;
                    break;

                case RepaymentDetail_No:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as RepaymentDetail).No;
                    content = tagValue;
                    break;
                case RepaymentDetail_Title:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as RepaymentDetail).Title;
                    content = tagValue;
                    break;
                case RepaymentDetail_Amount:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as RepaymentDetail).Amount;
                    content = tagValue;
                    break;
                case AmountRepayment:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).AmountRepayment;
                    content = tagValue;
                    break;
                case TotalAmount:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).TotalAmount;
                    content = tagValue;
                    break;
                case DifferentAmount:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).DifferentAmount;
                    content = tagValue;
                    break;
                case Currency:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).Currency;
                    content = tagValue;
                    break;

                case ReferenceRequest_No:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as ReferenceRequest).No;
                    content = tagValue;
                    break;
                case ReferenceRequest_Title:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as ReferenceRequest).Title;
                    content = tagValue;
                    break;
                case ReferenceRequest_DateRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as ReferenceRequest).DateRequest.ToString("dd/MM/yyyy");
                    content = tagValue;
                    break;
                case ReferenceRequest_UserRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as ReferenceRequest).UserRequest;
                    content = tagValue;
                    break;
                case ReferenceRequest_DepartmentRequest:
                    bubblePlaceHolder = false;
                    tagValue = ((openXmlElementDataContext.DataContext) as ReferenceRequest).DepartmentRequest;
                    content = tagValue;
                    break;
            }

            if (bubblePlaceHolder)
            {
                // Use base class code as tags are already defined in base class.
                base.NonRecursivePlaceholderFound(placeholderTag, openXmlElementDataContext);
            }
            else
            {
                // Set the tag for the content control
                if (!string.IsNullOrEmpty(tagValue))
                {
                    this.SetTagValue(openXmlElementDataContext.Element as SdtElement, GetFullTagValue(tagPlaceHolderValue, tagValue));
                }

                // Set the content for the content control
                this.SetContentOfContentControl(openXmlElementDataContext.Element as SdtElement, content);
            }
        }

        /// <summary>
        /// Recursive placeholder found.
        /// </summary>
        /// <param name="placeholderTag">The placeholder tag.</param>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        protected override void RecursivePlaceholderFound(string placeholderTag, OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (openXmlElementDataContext == null || openXmlElementDataContext.Element == null || openXmlElementDataContext.DataContext == null)
            {
                return;
            }

            string tagPlaceHolderValue = string.Empty;
            string tagGuidPart = string.Empty;
            GetTagValue(openXmlElementDataContext.Element as SdtElement, out tagPlaceHolderValue, out tagGuidPart);

            // Reuse base class code and handle only tags unavailable in base class
            bool bubblePlaceHolder = true;

            switch (tagPlaceHolderValue)
            {
                case RepaymentDetail:
                    bubblePlaceHolder = false;

                    foreach (RepaymentDetail repaymentDetail in ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).RepaymentDetails)
                    {
                        SdtElement clonedElement = this.CloneElementAndSetContentInPlaceholders(new OpenXmlElementDataContext() { Element = openXmlElementDataContext.Element, DataContext = repaymentDetail });
                    }

                    openXmlElementDataContext.Element.Remove();
                    break;
                case ReferenceRequest:
                    bubblePlaceHolder = false;

                    foreach (ReferenceRequest referenceRequest in ((openXmlElementDataContext.DataContext) as DeNghiHoanUngDataContext).ReferenceRequests)
                    {
                        SdtElement clonedElement = this.CloneElementAndSetContentInPlaceholders(new OpenXmlElementDataContext() { Element = openXmlElementDataContext.Element, DataContext = referenceRequest });
                    }

                    openXmlElementDataContext.Element.Remove();
                    break;
            }

            if (bubblePlaceHolder)
            {
                // Use base class code as tags are already defined in base class.
                base.RecursivePlaceholderFound(placeholderTag, openXmlElementDataContext);
            }
        }

        #endregion
    }
}
